package com.northpool.operator.analysis.dataset;

import com.northpool.operator.annotation.InputParam;
import com.northpool.operator.annotation.InputParams;
import com.northpool.operator.annotation.OperatorInfo;
import com.northpool.operator.common.database.DatabaseUtils;
import com.northpool.operator.common.stpclient.StpClientOperatorBase;
import com.northpool.operator.param.ParamTool;
import com.northpool.operator.param.custom.DatasetParam;
import com.northpool.operator.type.TypeEnum;
import com.northpool.resources.command.QueryFilter;
import com.northpool.spatial.grid.Constants;
import com.northpool.stpclient.bean.BaseResponse;
import com.northpool.stpclient.bean.overlay.SingleTableOverlayPlan;
import com.northpool.stpclient.modules.geoprocess.overlay.IOverlayOperator;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

@OperatorInfo(
        ref = "OverlaySelectOperator",
        name = "压盖选择",
        description = "将压盖的要素根据排序字段优先级选择保留。"
)
public class OverlaySelectOperator extends StpClientOperatorBase {

    @InputParams({
            @InputParam(ref = "dataset", name = "数据集", desc = "数据集包含数据源ID和数据表名称的JSON描述，如: {\"dataSourceId\":\"xxx-xxx\",\"tableName\":\"table\"}", type = TypeEnum.DB, required = true, testValue = ""),
            @InputParam(ref = "sqlFilter", name = "SQL过滤条件A", desc = "SQL过滤条件, 如: dlmc = '旱地'", type = TypeEnum.STRING, required = false, testValue = ""),
            @InputParam(ref = "sortFields", name = "排序字段", desc = "多个字段逗号隔开", type = TypeEnum.STRING, testValue = "dlbm_1", required = true),
            @InputParam(ref = "sortTypes", name = "排序字段类型", desc = "多个类型逗号隔开", type = TypeEnum.STRING, testValue = "ASC", required = true),
            @InputParam(ref = "gridUnit", name = "格网单位", desc = "瓦片格网单位，枚举值: degree、meter", type = TypeEnum.STRING,value = "degree", required = false),
            @InputParam(ref = "targetLevel", name = "数据处理层级", desc = "用于数据处理时的任务格网层级，根据数据量大小和图斑大小决定", value = "12", type = TypeEnum.STRING, required = false),
            @InputParam(ref = "targetDataSourceId", name = "目标数据源ID", desc = "目标数据源ID", type = TypeEnum.DATASOURCE, required = true, testValue = "storage"),
            @InputParam(ref = "targetTableName", name = "目标表名称", desc = "目标表名称", type = TypeEnum.STRING, required = true, testValue = "result.dltb2022_4301_select"),
    })
    public OverlaySelectOperator() {
        super();
    }

    @Override
    public void execute(ParamTool params) throws Exception {
        DatasetParam dataset = params.getDataset("dataset");
        String dataSourceId = dataset.getDataSourceId();
        String tableName = dataset.getTableName();

        String sqlFilter = params.getStr("sqlFilter");
        String sortFields = params.getStr("sortFields");
        String sortTypes = params.getStr("sortTypes");
        String gridUnit = params.getStr("gridUnit");
        String targetLevel = params.getStr("targetLevel");
        String targetDataSourceId = params.getStr("targetDataSourceId");
        String targetTableName = params.getStr("targetTableName");
        String spatialRelation = "WITHIN";

        String dataSourceJson = DatabaseUtils.getDataSourceJson(dataSourceId);
        String targetDataSourceJson = DatabaseUtils.getDataSourceJson(targetDataSourceId);

        String[] sortFieldArr = sortFields.split(",");
        String[] sortTypeStrArr = sortTypes.split(",");

        QueryFilter.SORT[] sortArr = new QueryFilter.SORT[sortTypeStrArr.length];
        for (int i = 0; i < sortTypeStrArr.length; i++) {
            String typeStr = sortTypeStrArr[i];
            if (StringUtils.isBlank(typeStr)) {
               this.error("字段排序类型错误，只支持 ASC 、DESC, 当前错误的值为: " + typeStr);
               this.failedExit();
            }
            QueryFilter.SORT sort = QueryFilter.SORT.valueOf(typeStr);
            sortArr[i] = sort;
        }
        if (sortArr.length != sortFieldArr.length) {
            this.error("排序字段数量和排序字段类型数量不一致: " + ArrayUtils.toString(sortFields) + "; sortTypes: " + ArrayUtils.toString(sortTypes));
            this.failedExit();
        }

        IOverlayOperator operator = this.client.overlayOperator();
        SingleTableOverlayPlan plan = new SingleTableOverlayPlan();
        plan.setDataSourceStr(dataSourceJson);
        plan.setTableName(tableName);
        plan.setSqlFilter(sqlFilter);
        plan.setSortFields(sortFieldArr);
        plan.setSortTypes(sortArr);
        plan.setGridUnit(Constants.GRID_UNIT.valueOf(gridUnit));
        plan.setSpatialRelation(com.northpool.resources.command.Constants.OPERATION.valueOf(spatialRelation));

        plan.setTargetLevel(Integer.valueOf(targetLevel));
        plan.setTargetDataSourceStr(targetDataSourceJson);
        plan.setTargetTableName(targetTableName);

        BaseResponse response = operator.startOverlaySelect(plan);

        String requestId = response.getRequestId();
        operator.onStart(requestId, () -> {
            this.log("压盖选择开始");
        });
        operator.onSuccess(requestId, () -> {
            this.log("压盖选择成功");
            String log = operator.log(response.getRequestId());
            this.log(log);
            this.successExit();
        });
        operator.onError(requestId, () -> {
            this.error("压盖选择失败");
            String log = operator.log(response.getRequestId());
            this.error(log);
            this.failedExit();
        });
        this.waiting(24);
    }
}
